package com.example.animations.transitions;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.transition.Transition;
import androidx.transition.TransitionListenerAdapter;
import androidx.transition.TransitionValues;
import androidx.transition.Visibility;

public class ScaleTransition extends Visibility {
    private final String SCALE_X_KEY = "scale_x";
    private final String SCALE_Y_KEY = "scale_y";

    @Override
    public void captureStartValues(@NonNull TransitionValues transitionValues) {
        super.captureStartValues(transitionValues);
        // Setting the current view scale as start point
        transitionValues.values.put(SCALE_X_KEY, transitionValues.view.getScaleX());
        transitionValues.values.put(SCALE_Y_KEY, transitionValues.view.getScaleY());
    }

    @Override
    public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
        Object startScaleX = startValues.values.get(SCALE_X_KEY);
        Object startScaleY = startValues.values.get(SCALE_Y_KEY);

        float startX = 0f;
        float startY = 0f;

        if (startScaleX != null) startX = (float)startScaleX;
        if (startScaleY != null) startY = (float)startScaleY;

        return createScaleAnimator(view, startX == 1f ? 0f : startX, startY == 1f ? 0f : startY, 1f, 1f);
    }

    @Override
    public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues, TransitionValues endValues) {
        Object startScaleX = startValues.values.get(SCALE_X_KEY);
        Object startScaleY = startValues.values.get(SCALE_Y_KEY);

        float startX = 1f;
        float startY = 1f;

        if (startScaleX != null) startX = (float)startScaleX;
        if (startScaleY != null) startY = (float)startScaleY;

        return createScaleAnimator(view, startX, startY, 0f, 0f);
    }

    private Animator createScaleAnimator(View view, float startX, float startY, float endX, float endY) {
        ObjectAnimator xAnimator = ObjectAnimator.ofFloat(view, View.SCALE_X, startX, endX);
        ObjectAnimator yAnimator = ObjectAnimator.ofFloat(view, View.SCALE_Y, startY, endY);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(xAnimator, yAnimator);

        animatorSet.addListener(getAnimatorListener(view));
        addListener(getTransitionListener(view));

        return animatorSet;
    }

    private Animator.AnimatorListener getAnimatorListener(View view) {
        return new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                onTransitionEnded(view);
            }
        };
    }

    private TransitionListener getTransitionListener(View view) {
        return new TransitionListenerAdapter(){
            @Override
            public void onTransitionEnd(@NonNull Transition transition) {
                onTransitionEnded(view);
            }
        };
    }

    private void onTransitionEnded(View view) {
        view.setScaleX(1f);
        view.setScaleY(1f);
    }
}